import javax.swing.*;
import java.io.*;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Stream;

public class RenameWorker extends SwingWorker<Integer, Integer> {
	JButton button;
	JLabel progress;
	String errMsg;
	File dir;
	List<File> files;
	public static final String prefix = "src\\main\\java";

	public RenameWorker(File dir, JButton button, JLabel progress) {
		this.dir = dir;
		this.button = button;
		this.progress = progress;
	}

	@Override
	protected Integer doInBackground() {
		try {
			files = descendants(dir)
					.filter(file -> file.getName().endsWith(".java"))
					.toList();
			AtomicInteger count = new AtomicInteger();
			files.forEach(file -> {
				String path = file.getAbsolutePath();
				if (!path.contains(prefix)) return;
				String packageName = path.substring(path.lastIndexOf(prefix) + 14,
						path.lastIndexOf("\\")).replaceAll("\\\\", "\\.");

				StringBuilder builder = new StringBuilder();
				try (BufferedReader br = new BufferedReader(new FileReader(file))) {
					String s;
					while ((s = br.readLine()) != null) {
						if (s.startsWith("package"))
							s = "package " + packageName + ";";
						builder.append(s).append("\n");
					}
					br.close();
					try (BufferedWriter bw = new BufferedWriter(new FileWriter(file))) {
						bw.write(builder.toString());
					}
				} catch (IOException e) {
					errMsg = e.getMessage();
				}
				publish(count.incrementAndGet());
			});
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	@Override
	protected void process(List<Integer> chunks) {
		progress.setText(String.format("%.2f%%", chunks.get(chunks.size() - 1) * 1f / files.size() * 100));
	}

	public static Stream<File> descendants(File f) {
		return Stream.of(Objects.requireNonNullElse(f.listFiles(), new File[0]))
				.flatMap(m -> Stream.concat(Stream.of(m), descendants(m)))
				.filter(File::isFile);
	}

	@Override
	protected void done() {
		if (errMsg == null) {
			JOptionPane.showConfirmDialog(null, "包名重命名完成", "提示", JOptionPane.DEFAULT_OPTION);
		} else {
			JOptionPane.showConfirmDialog(null, "重命名失败：" + errMsg, "错误",
					JOptionPane.DEFAULT_OPTION, JOptionPane.ERROR_MESSAGE);
		}
		button.setEnabled(true);
	}
}
